package com.example.goodsmanagementcabinet.hcamburntool;

import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.util.Log;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static android.content.Context.USB_SERVICE;

/**
 * name: VersionTools2051B<p>
 * description 2051B 的升级工具实现类<p>
 *
 * @author YCKJ0165 <P>
 * date: 6/30/2020 <p>
 * copy: 重庆中科云从科技有限公司 <p>
 */
public class VersionTools2051B {
    private static final String TAG = "VersionTools2051B";
    private static VersionTools2051B VersionTools2051B = new VersionTools2051B();
    private Map<String, String> map = new HashMap<>();
    private boolean isInit;

    /**
     * 烧录操作
     */
    public hcamBurnOp mhCamBurnOp;

    private String deviceSerial;

    private String firmVersion;


    private VersionTools2051B() {
        if (!isInit) {
            init();
            isInit = true;
        }
    }

    public static VersionTools2051B getInstance() {
        return VersionTools2051B;
    }

    private void init() {
        mhCamBurnOp = new hcamBurnOp();
        //初始化烧录
        mhCamBurnOp.hcamBurnOpInit();
        //检查usb设备的权限
        //checkDevicePermission();
        //获取usb信息

    }

    @SuppressLint("NewApi")
    private String getFirmVersion(int fileDescriptor, UsbDevice usbDevice) {
        String result = "";
        if (mhCamBurnOp == null) {
            return result;
        }
        int ret = mhCamBurnOp.openDevice(fileDescriptor, usbDevice.getDeviceName());
        if (ret >= 0) {
            if (1 == ret) {
                //打开
                if (mhCamBurnOp.getDeviceSerial() != null && mhCamBurnOp.getDeviceSerial().length > 0) {
                    result = firmVersion = Integer.toHexString(mhCamBurnOp.getDeviceBCD());
                    return result;
                }
            }
        }
        closeDevice();
        return result;
    }

    public void closeDevice() {
        if (mhCamBurnOp != null) {
            mhCamBurnOp.close();
        }
    }

    /**
     * functionName: getDeviceList <p>
     * description: 获取设备版本号<p>
     * params:  <p>
     * return: void <p>
     * author:  <p>
     * date: 7/1/2020 <p>
     */
    @SuppressLint("NewApi")
    public void initDeviceVersion(Context context, VersionCallBack ok) {
        //初始化设备参数
        UsbManager mUsbManager = (UsbManager) context.getSystemService(USB_SERVICE);
        HashMap<String, UsbDevice> mDeviceList = mUsbManager.getDeviceList();
        Iterator<UsbDevice> mDeviceIterator = mDeviceList.values().iterator();
        if (mDeviceIterator != null) {
            while (mDeviceIterator.hasNext()) {
                final UsbDevice usbDeviceFocus = mDeviceIterator.next();
                // 判断是否为UVC设备
                if (is2051BCamera(usbDeviceFocus) && checkUVCDevice(usbDeviceFocus)) {
                    Log.e(TAG, "getDeviceList: checkUVCDevice " + String.format("%x", usbDeviceFocus.getProductId()));
                    // 已经有权限继续操作设备
                    if (mUsbManager.hasPermission(usbDeviceFocus)) {
                        Log.e(TAG, "getDeviceList: has  hasPermission" + String.format("%x", usbDeviceFocus.getProductId()));
                        //  判断设备属性
                        final UsbDeviceConnection usbDevConnection = mUsbManager.openDevice(usbDeviceFocus);
                        if (null != usbDevConnection) {
                            int fileDescriptor = usbDevConnection.getFileDescriptor();
                            String fimVersion = getFirmVersion(fileDescriptor, usbDeviceFocus);
                            map.put(usbDeviceFocus.getProductName(), fimVersion);
                        }
                        if (usbDevConnection != null) {
                            usbDevConnection.close();
                        }
                    }
                }
            }
            if (ok != null) {
                ok.onSuccess();
            }
        }
    }

    private boolean is2051BCamera(UsbDevice device) {
        return device.getVendorId() == 3141 && (device.getProductId() == 49235 || device.getProductId() == 45137);
    }

    public interface VersionCallBack {
        void onSuccess();
    }

    public String getFirmVersion(String deviceProductName) {
        return map.get(deviceProductName);
    }

    public Map getAllFirmVersion() {
        return map;
    }

    /**
     * 设备过滤
     *
     * @param oUsbDevice
     * @return
     */
    private boolean checkUVCDevice(UsbDevice oUsbDevice) {
        boolean tmp_bRet = false;
        UsbInterface tmp_oUsbInterface;
        int tmp_sDeviceClass = 0;
        int tmp_sDeviceSubClass = 0;
        int tmp_sDeviceProtocol = 0;
        int tmp_sInterfaceClass = 0;

        if (null != oUsbDevice) {
            // Debug output device protocol
            Log.d("DevAttr", "DeviceClass=" + Integer.toHexString(oUsbDevice.getDeviceClass()) + " SubClass=" + Integer.toHexString(oUsbDevice.getDeviceSubclass()) + " Protocol=" + Integer.toHexString(oUsbDevice.getDeviceProtocol()) + ".\n");
            // Get interface 0
            tmp_oUsbInterface = oUsbDevice.getInterface(0);

            tmp_sDeviceClass = oUsbDevice.getDeviceClass();
            tmp_sDeviceSubClass = oUsbDevice.getDeviceSubclass();
            tmp_sDeviceProtocol = oUsbDevice.getDeviceProtocol();
            if (null != tmp_oUsbInterface) {
                tmp_sInterfaceClass = tmp_oUsbInterface.getInterfaceClass();
                Log.d("Interface0", "FuncClass=" + Integer.toHexString(tmp_oUsbInterface.getInterfaceClass()) + " SubClass=" + Integer.toHexString(tmp_oUsbInterface.getInterfaceSubclass()) + " Protocol=" + Integer.toHexString(tmp_oUsbInterface.getInterfaceProtocol()) + ".\n");
            }

            if ((0xEF == tmp_sDeviceClass)          // Base class
                    && (0x02 == tmp_sDeviceSubClass)
                    && (0x01 == tmp_sDeviceProtocol)    // Interface Association Descriptor
                    && (0x0E == tmp_sInterfaceClass))   // Video
            {
                tmp_bRet = true;
            }
        }
        return tmp_bRet;
    }
}
